<?php

/*
 * Codeginiter User Manager Class @author Carlos O Carvalho @site carlosorvalho.com.br @dependency Class Utils
 */

class User_Manager {
    /*
     * table users var public $_table
     */

    public $_table = 'users';

    /*
     * log errors var private errors
     */
    private $errors = array();

    /*
     * var fields_users
     */
    private $fields_user_table = array();

    /*
     * array _config local loaded file user_manager.php var _config
     */

    function __construct() {
        $this->CI = & get_instance();
        $this->CI->load->database();
        $this->CI->config->load('user_manager', true);
        $this->_config = (object) $this->CI->config->item('user_manager');
        $this->fields_user_table = $this->_config->columns_user;
        log_message('debug', 'Class User Manager Loaded');
    }

    function get_errors() {
        return implode('\n', $this->errors);
    }

    function _encrypt($pwd) {
        return hash('sha512', $pwd);
    }

    function register($data = array(), $group = 1) {
        if (count($data) < 1) {
            $this->errors [] = Utils::message('no_send_data');
            return false;
        }

        if (!$this->find_user($data ['LOGIN'])) {
            // initialize start transiction
            $this->CI->db->trans_start();
            // newuser

            $user_data = $this->_extract_data_array($data);
            if (isset($user_data ['PWD']) && $user_data ['PWD'] != '') {
                $user_data ['PWD'] = $this->_encrypt($user_data ['PWD']);
            }
            $user_data ['USER_KEY'] = Utils::generateKeyActivation();
            $user_data ['GROUP_ID'] = $group;
            $this->CI->db->set($user_data);
            $this->CI->db->insert('users');
            $qr = $this->CI->db->query('SELECT LAST_INSERT_ID()');

            $row = (array) $qr->row();
            $last_id = $row ['LAST_INSERT_ID()'];
            $data = $this->_remove_data_array($data);
            $data ['USER_ID'] = $last_id;
            $this->CI->db->set($data);
            $this->CI->db->insert('profiles');
            $this->CI->db->trans_complete();

            if ($this->CI->db->trans_status() === FALSE) {
                return false;
            }
            return true;
        }
        $this->errors [] = Utils::message('is_duplicate_data');
        return false;
    }

    function _remove_data_array($data) {
        if (count($data) > 0) {
            foreach ($this->fields_user_table as $field) :
                if (isset($data [$field])) {
                    unset($data [$field]);
                }
            endforeach
            ;
            return $data;
        }
    }

    function _extract_data_array($data) {
        if (count($data) > 0) {
            $d_return = array();

            foreach ($this->fields_user_table as $field) :
                if (isset($data [$field]) && $data[$field] != '') {
                    $d_return [$field] = $data [$field];
                }
            endforeach
            ;
            if (count($d_return) > 0) {
                return $d_return;
            }
            return false;
        }
        return false;
    }

    function unregister($id) {
        $this->CI->db->trans_start();
        $this->CI->db->delete('users', array(
            'ID' => $id
                ), 1);
        $this->CI->db->delete('profiles', array(
            'USER_ID' => $id
        ));
        $this->CI->db->trans_complete();
        return $this->CI->db->trans_status();
    }

    function find_user($login) {
        $this->CI->db->where('LOGIN', $login);
        $user = $this->CI->db->get('users');
        return $user->num_rows() > 0 ? $user->row() : false;
    }

    function get_profile($user_id) {
        return $this->CI->db->get_where('profiles', array(
                    'USER_ID' => $id
                ))->row();
    }

    function get_users($id = null, $group_id = null) {
        $m = 'result';
        $this->CI->db->select('p.*,g.HOME_PAGE,g.NOME as MY_GROUP,u.*')
                ->from('users as u')
                ->join('groups as g', 'g.ID=u.GROUP_ID')
                ->join('profiles as p', 'p.USER_ID=u.ID');

        if (!is_null($id)) {
            $this->CI->db->where('u.ID', $id);
            $m = 'row';
        }

        if (!is_null($group_id)) {
            if (is_string($group_id)) {
                $this->CI->db->where($group_id);
            } else {

                $this->CI->db->where('u.GROUP_ID', $group_id);
            }
        }
        return $this->CI->db->get()->$m();
    }

    function get_where($where, $single = false) {
        $m = $single ? 'row' : 'result';
        $this->CI->db->select('p.*,g.HOME_PAGE,g.NOME as MY_GROUP,u.*')
                ->from('users as u')
                ->join('groups as g', 'g.ID=u.GROUP_ID')
                ->join('profiles as p', 'p.USER_ID=u.ID');
        $this->CI->db->where($where);

        return $this->CI->db->get()->$m();
    }

    function get_by_email($email) {

        $this->CI->db->select('p.*,g.HOME_PAGE,g.NOME as MY_GROUP,u.*')
                ->from('users as u')
                ->join('groups as g', 'g.ID=u.GROUP_ID')
                ->join('profiles as p', 'p.USER_ID=u.ID');
        $this->CI->db->where('p.EMAIL', $email);

        $q = $this->CI->db->get();
        if ($q->num_rows() == 0) {
            return false;
        }
        return $q->row();
    }

    function get_by($where) {

        $this->CI->db->select('p.*,g.HOME_PAGE,g.NOME as MY_GROUP,u.*')
                ->from('users as u')
                ->join('groups as g', 'g.ID=u.GROUP_ID')
                ->join('profiles as p', 'p.USER_ID=u.ID');
        $this->CI->db->where($where);

        $q = $this->CI->db->get();
        if ($q->num_rows() == 0) {
            return false;
        }
        return $q->row();
    }

    function update($data, $id) {
        if (isset($data ['PWD']) && $data ['PWD'] != '') {
            $data ['PWD'] = $this->_encrypt($data ['PWD']);
        }
        if (isset($data['LOGIN'])) {
            $find = $this->find_user($data['LOGIN']);
            if ($find) {
                if ($find->ID != $id) {
                    return false;
                }
            }
        }
        $this->CI->db->trans_start();
        //exists data in array udpate
        $user_update = $this->_extract_data_array($data);
        if ($user_update) {
            foreach ($user_update as $key => $val) {
                $this->CI->db->set($key, $val);
            }
            $this->CI->db->where(array(
                'ID' => $id
            ));
            $this->CI->db->update('users');
        }
        $p = $this->_remove_data_array($data);
        if (count($p) > 0) {
            foreach ($p as $key => $val) {
                $this->CI->db->set($key, $val);
            }

            $this->CI->db->where(array(
                'USER_ID' => $id
            ));
            $this->CI->db->update('profiles');
        }
        $this->CI->db->trans_complete();
        return $this->CI->db->trans_status();
    }

    function auth($user, $pwd) {

        $db = $this->CI->db;

        $db->select('g.HOME_PAGE as PAGE,g.NOME as GROUP_NAME,u.*')
                ->from('users as u')
                ->join('groups as g', 'g.ID=u.GROUP_ID')
                ->where(array('u.LOGIN' => $user, 'u.PWD' => hash('sha512', $pwd)));
        $r = $db->get();
        if ($r->num_rows() > 0) {
            $row = $r->row();
            $config = array('login' => $row->LOGIN, 'token' => $row->USER_KEY, 'page' => $row->PAGE, 'group' => $row->GROUP_NAME, 'id' => $row->ID);
            $config['loggedin'] = true;
            $this->CI->session->set_userdata('user_data', $config);

            return (object) $config;
        }

        return false;
    }

    function is_loggedin() {
        $user = $this->CI->session->userdata('user_data');
        return $user;
    }

    function logout() {
        $user = array('login' => 'login', 'token' => 0, 'page' => 0, 'group' => 'visitante', 'id' => 0, 'loggedin' => false);
        $this->CI->session->set_userdata('user_data', $user);
        $this->CI->session->sess_destroy();
        $this->CI->session->sess_create();

        $user_data = $this->CI->session->all_userdata();

        foreach ($user_data as $key => $value) {
            if ($key != 'session_id' && $key != 'ip_address' && $key != 'user_agent' && $key != 'last_activity') {
                $this->CI->session->unset_userdata($key);
            }
        }
    }

    function get_groups($id = null) {
        if (!is_null($id)) {
            $this->CI->db->where('ID', $id);
        }
        return $this->CI->db->get('groups')->result();
    }

    function online() {
        $config = (object) $this->CI->config->config;
        $sql = "SELECT * FROM `{$config->sess_table_name}` WHERE `last_activity` >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 14 MINUTE)) ";
        $q = $this->CI->db->query($sql);
        return $q->result();
    }

}
